
/**
 * Js上传文件至阿里云oss
 * @param {Object} optPar 配置参数
 * optPar = {
 *     uploadButId:'select-file',//选择的按钮id
 *     accessid:'accessid',
 *     accesskey:'accesskey',
 *     host:'host',
 *     dir:'test',//不含开头的斜杠和结尾的斜杆
 *     onceMulti:fase,//一次可选择多张
 *
 *     generateName:'random'//random|timestamp|designation|same 文件名生成方式
 *     fileName:''//当 generateName==designation 时有效（文件名不能包含斜杆）
 * }
 *
 * @param {Object} statusPar 操作回调
 * statusPar = {
 *     added:function(file){},//选择了文件触发（返回false可以停止该文件上传，可用于过滤文件类型）
 *     before:function(file){},//上传前
 *     progress:function(file){},//生成中重复触发 file.percent 上传进度
 *     success:function(file,info){},//上传成功 file.finallyRes 最终路径
 *     error:function(file,info){},//上传失败
 * }
 *
 * @return {Object} obj 返回该类实例
 *
 * @since 1.0.0
 * @author LWQ
 * */
function OssJsUpload(optPar,statusPar) {
    optPar = typeof optPar == 'object' ? optPar : {};
    statusPar = typeof statusPar == 'object' ? statusPar : {};

    optPar.generateName=['random','timestamp','designation','same'].indexOf(optPar.generateName)>-1?optPar.generateName:'random';
    optPar.fileName=typeof optPar.fileName=='string'?optPar.fileName:'';
    optPar.fileName.replace(/\/|\\/,'');

    statusPar.added = typeof statusPar.added == 'function' ? statusPar.added : function () {
    };
    statusPar.before = typeof statusPar.before == 'function' ? statusPar.before : function () {
    };
    statusPar.progress = typeof statusPar.progress == 'function' ? statusPar.progress : function () {
    };
    statusPar.success = typeof statusPar.success == 'function' ? statusPar.success : function () {
    };
    statusPar.error = typeof statusPar.error == 'function' ? statusPar.error : function () {
    };


    //一堆代码
    var g_dirname = '';
    var g_object_name = '';
    var g_object_name_type = 'random_name';//local_name | random_name
    var suffix = '';
    var timestamp = Date.parse(new Date()) / 1000;
    var now = timestamp;

    var policyText = {
        "expiration": "2030-01-01T12:00:00.000Z", //设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了
        "conditions": [
            ["content-length-range", 0, 1048576000] // 设置上传文件的大小限制
        ]
    };

    var policyBase64 = Base64.encode(JSON.stringify(policyText))
    var message = policyBase64
    var bytes = Crypto.HMAC(Crypto.SHA1, message, optPar.accesskey, {asBytes: true});
    var signature = Crypto.util.bytesToBase64(bytes);

    function get_dirname() {
        var dir = optPar.dir;
        if (dir != '' && dir.indexOf('/') != dir.length - 1) {
            dir = dir + '/'
        }
        //alert(dir)
        g_dirname = dir
    }

    function random_string(len) {
        len = len || 32;
        var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
        var maxPos = chars.length;
        var pwd = '';
        for (i = 0; i < len; i++) {
            pwd += chars.charAt(Math.floor(Math.random() * maxPos));
        }
        return pwd;
    }

    function get_suffix(filename) {
        var pos = filename.lastIndexOf('.')
        suffix = ''
        if (pos != -1) {
            suffix = filename.substring(pos)
        }
        return suffix;
    }

    function calculate_object_name(filename) {
        switch(optPar.generateName){
            case 'random':
                suffix = get_suffix(filename)
                g_object_name = g_dirname + random_string(10) + suffix
                break;
            case 'timestamp':
                suffix = get_suffix(filename)
                g_object_name = g_dirname + (new Date()).getTime() + suffix
                break;
            case 'designation':
                suffix = get_suffix(filename)
                g_object_name = g_dirname + optPar.fileName + suffix
                break;
            case 'same':
                g_object_name += "${filename}"
                break;
        }
        return ''
    }

    function get_uploaded_object_name(filename) {
        switch(optPar.generateName){
            case 'random':
                return g_object_name
            case 'timestamp':
                return g_object_name
            case 'designation':
                return g_object_name
            case 'same':
                var tmp_name = g_object_name
                tmp_name = tmp_name.replace("${filename}", filename);
                return tmp_name
        }
    }

    function set_upload_param(up, filename, ret) {
        g_object_name = g_dirname;
        if (filename != '') {
            suffix = get_suffix(filename)
            calculate_object_name(filename)
        }
        var new_multipart_params = {
            'key': g_object_name,
            'policy': policyBase64,
            'OSSAccessKeyId': optPar.accessid,
            'success_action_status': '200', //让服务端返回200,不然，默认会返回204
            'signature': signature,
        };

        up.setOption({
            'url': optPar.host,
            'multipart_params': new_multipart_params
        });

        up.start();
    }

    var uploader = new plupload.Uploader({
        runtimes: 'html5,flash,silverlight,html4',
        browse_button: optPar.uploadButId,
        multi_selection: !!optPar.onceMulti,
        flash_swf_url: 'oss-js-upload.js/lib/plupload-2.1.2/js/Moxie.swf',
        silverlight_xap_url: 'oss-js-upload.js/lib/plupload-2.1.2/js/Moxie.xap',
        url: 'http://oss.aliyuncs.com',

        init: {
            PostInit: function () {
                //oss初始化
            },

            FilesAdded: function (up, files) {
                var list=[];
                for(var i=0,len=files.length;i<len;i++){
                    if(statusPar.added(files[i])!==false)
                        list.push(files[i]);
                    else
                        up.removeFile(files[i].id);
                }

                plupload.each(list, function (file) {
                    statusPar.added(file);
                });

                set_upload_param(uploader, '', false);
            },

            BeforeUpload: function (up, file) {
                get_dirname();
                set_upload_param(up, file.name, true);
                file.finallyRes=get_uploaded_object_name(file.name);
                statusPar.before(file);
            },

            UploadProgress: function (up, file) {
                statusPar.progress(file);
            },

            FileUploaded: function (up, file, info) {
                if (info.status == 200)
                    statusPar.success(file, info);
                else
                    statusPar.error(file, info);
            },

            Error: function (up, err) {
                statusPar.error({}, err);
            }
        }
    });
    uploader.init();
}